package at.ac.tuwien.prog;

import java.io.Closeable;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import at.ac.tuwien.prog.command.AddConstantCommand;

/**
 * 
 * @author christoph.pickl@student.tuwien.ac.at
 */
public final class Util {

	private static final Log LOG = LogFactory.getLog(AddConstantCommand.class);
	

	public static int extractNumber(int fullBits, int fromIndex, int toIndex) {
		final int bitMask = createBitMask(fromIndex, toIndex);
//		LOG.trace("bitMask: " + Util.toBitString(bitMask));
		final int result = (fullBits & bitMask) >>> fromIndex;
		
//		LOG.trace("extractNumber(fullBits="+fullBits+"; from/to="+fromIndex+"/"+toIndex+") => " + result);
//		LOG.trace("  fullBits in bits: " + Util.toBitString(fullBits));
//		LOG.trace("  result in bits: " + Util.toBitString(result));
		return result;
	}

	private static int createBitMask(final int fromIndex, final int toIndex) {
		final int range = toIndex - fromIndex;
		
		int mask = 0;

		for (int i = 0; i < range; i++) {
			mask = mask << 1;
			mask++;
		}
		
		for (int i = 0; i < fromIndex; i++) {
			mask = mask << 1;
		}
		
		return mask;
	}
	
	
	
	public static void close(Closeable... closeables) {
		if(closeables == null) {
			return;
		}
		
		for (final Closeable closeable : closeables) {
			if(closeable != null) {
				try {
					closeable.close();
				} catch (IOException e) {
					LOG.warn("Could not close closeable.", e);
				}
			}
		}
	}

	/**
	 * for debugging purposes only.
	 */
	public static String toBitString(final byte... bytes) {
		final StringBuilder sb = new StringBuilder(32);
		
		for (byte b : bytes) {
			for (int i = 0; i < 8; i++) {
				int mask = 1 << i;
				sb.insert(0, (mask & b) != 0 ? "1" : "0");
			}
		}
		
		return sb.toString();
	}
	
	public static String toBitString(final int number) {
		final StringBuilder sb = new StringBuilder(32);
		
		for (int i = 0; i < 32; i++) {
			int mask = 1 << i;
			sb.insert(0, (mask & number) != 0 ? "1" : "0");
		}
		
		return sb.toString();
	}
	
	private Util() {
		// no instantiation
	}
	
}
